import io

from aiogram import Bot, Dispatcher, F
from aiogram.filters import Text
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import any_state
from aiogram.types import Message, ReplyKeyboardRemove
from sqlalchemy.ext.asyncio import AsyncSession

from app.bot.keyboards.reply import add_more_keyboard
from app.bot.states.states import DolphinAccs
from app.bot.utils.dolphin import add_account, check_token
from app.database.functions.stats import update_stats, update_user_stats


async def dolphin_add_accounts(message: Message, state: FSMContext) -> None:
    """
    Добавление аккаунтов в Dolphin
    """

    txt = (
        f"{message.from_user.first_name}, добро пожаловать в сервис для переноса аккаунтов в Ваш Dolphin автозалив\n\n"
        f"<b>Отправьте IP панели Dolphin </b>автозалив в формате http://168.16.627.67\n\n"
        f"А так же у нас есть готовый сервис для фарма трастовых аккаунтов и переноса их в Dolphin автозалив без каких либо проблем и все это на полном автоматие - socrobotic.ru\n"
    )
    await message.answer(txt, reply_markup=ReplyKeyboardRemove())
    await message.answer("Отправьте /cancel, чтобы вернуться в главное меню")
    await state.set_state(DolphinAccs.waiting_url)


async def add_url(message: Message, state: FSMContext) -> None:
    if "http" not in message.text:
        await message.answer("Введите корректный IP панели")
        await state.set_state(DolphinAccs.waiting_url)
        return
    txt = (
        f"Введите токен от панели\n"
        f"Как получить токен: https://t.me/fb_update/2750\n"
    )
    await state.update_data(url=message.text)
    await message.answer(txt)
    await state.set_state(DolphinAccs.waiting_token)


async def add_token(message: Message, state: FSMContext) -> None:
    if "-" in message.text:
        data = await state.get_data()
        token_status = await check_token(data.get("url"), message.text)
        if not token_status:
            await message.answer("Введен невалидный токен. Введите правильный токен")
            await state.set_state(DolphinAccs.waiting_token)
            return
        await state.update_data(token=message.text)
        txt = (
            f"Отправьте мне аккаунт(ы) каждый с новой строки в формате <b>Имя|Пароль|Куки в формате json|Юзерагент|токен EAAB</b>\n"
            f"Куки должны быть в одну строчку\n"
            f"Аккаунты также можно отправить файлом\n"
        )
        await message.answer(txt)
        await state.set_state(DolphinAccs.waiting_accounts)
    if "еще" in message.text:
        txt = (
            f"Отправьте мне аккаунт(ы) каждый с новой строки в формате <b>Имя|Пароль|Куки в формате json|Юзерагент|токен EAAB</b>\n"
            f"Куки должны быть в одну строчку\n"
            f"Аккаунты также можно отправить файлом\n"
        )
        await message.answer(txt, reply_markup=ReplyKeyboardRemove())
        await state.set_state(DolphinAccs.waiting_accounts)


async def add_accounts(
    message: Message, bot: Bot, session: AsyncSession, state: FSMContext
) -> None:
    if message.document:
        if ".txt" not in message.document.file_name:
            await message.answer("Вы прислали не txt файл")
            await state.set_state(DolphinAccs.waiting_accounts)
            return
        else:
            file = io.BytesIO()
            await bot.download(message.document, destination=file)
            file_text = [line.decode() for line in file.readlines()]
            if "|" not in str(file_text):
                txt = (
                    f"В файле отсутствует разделитель <b>|</b>\n"
                    f"Пожалуйста, проверьте файл и загрузите его заново\n"
                )
                await message.answer(txt)
                await state.set_state(DolphinAccs.waiting_accounts)
                return
            else:
                accounts = [list(account.strip().split("|")) for account in file_text]
                data = await state.get_data()
                for account in accounts:
                    if len(account) != 5:
                        await message.answer(
                            f"Аккаунт {'|'.join(account)} не был добавлен, так как вы не указали пропуск вместо недостающего значения(ий)"
                        )
                        accounts.remove(account)
                    else:
                        account_status = await add_account(
                            data.get("url"), data.get("token"), account
                        )
                        if not account_status or not account_status.get("success"):
                            await message.answer(
                                f"Аккаунт {'|'.join(account)} не был добавлен из-за ошибки"
                            )
                            accounts.remove(account)
                if len(accounts) > 1:
                    await message.answer(
                        f"Добавлено аккаунтов: {len(accounts)}",
                        reply_markup=add_more_keyboard(),
                    )
                elif len(accounts) > 0:
                    await message.answer(
                        "Аккаунт добавлен", reply_markup=add_more_keyboard()
                    )
                else:
                    await message.answer(
                        "Ни один из аккаунтов не был добавлен, исправьте ошибки и загрузите их снова",
                        reply_markup=add_more_keyboard(),
                    )
                    await state.set_state(DolphinAccs.waiting_accounts)
                    return
                await update_stats(session, dolphin_accs=len(accounts))
                await update_user_stats(
                    session,
                    message.from_user.id,
                    dolphin_accs_loaded=len(accounts),
                )
                await state.clear()
    elif message.text:
        if "|" not in message.text:
            txt = (
                f"В списке отсутствует разделитель <b>|</b>\n"
                f"Пожалуйста, проверьте список и отправьте его заново\n"
            )
            await message.answer(txt)
            await state.set_state(DolphinAccs.waiting_accounts)
            return
        else:
            accounts = [
                list(account.strip().split("|")) for account in message.text.split("\n")
            ]
            data = await state.get_data()
            for account in accounts:
                if len(account) != 5:
                    await message.answer(
                        f"Аккаунт {'|'.join(account)} не был добавлен, так как вы не указали пропуск вместо недостающего значения(ий)"
                    )
                    accounts.remove(account)
                else:
                    account_status = await add_account(
                        data.get("url"), data.get("token"), account
                    )
                    if not account_status or not account_status.get("success"):
                        error_msg = account_status.get("message")
                        await message.answer(
                            f"Аккаунт {'|'.join(account)} не был добавлен из-за ошибки '{error_msg}'"
                        )
                        accounts.remove(account)
            if len(accounts) > 1:
                await message.answer(
                    f"Добавлено аккаунтов: {len(accounts)}",
                    reply_markup=add_more_keyboard(),
                )
            elif len(accounts) > 0:
                await message.answer(
                    "Аккаунт добавлен", reply_markup=add_more_keyboard()
                )
            else:
                await message.answer(
                    "Ни один из аккаунтов не был добавлен, исправьте ошибки и загрузите их снова"
                )
                await state.set_state(DolphinAccs.waiting_accounts)
                return
            await update_stats(
                session,
                dolphin_accs=len(accounts),
            )
            await update_user_stats(
                session, message.from_user.id, dolphin_accs_loaded=len(accounts)
            )


def register_dolphin_handlers(dp: Dispatcher):
    dp.message.register(
        dolphin_add_accounts,
        Text(text="🐬 Залив в Dolphin", ignore_case=True),
        any_state,
    )
    dp.message.register(add_url, DolphinAccs.waiting_url)
    dp.message.register(
        add_token, Text(text="Добавить еще аккаунт(ы)", ignore_case=True), any_state
    )
    dp.message.register(add_token, DolphinAccs.waiting_token)
    dp.message.register(
        add_accounts,
        DolphinAccs.waiting_accounts,
        F.content_type.in_(["text", "document"]),
    )
    # dp.register_message_handler(waiting_confirmation, state=DolphinAccs.waiting_confirmation)
